import functools
import json
from xml.dom import UserDataHandler

from flask import (
    Blueprint, current_app, flash, g, redirect, render_template, request, session, url_for,Response,abort,jsonify
)
from werkzeug.security import check_password_hash, generate_password_hash

from flaskr.db import get_db

from flask_cors import *

bp = Blueprint('vaccine', __name__, url_prefix='/')

cors=CORS(bp,supports_credentials=True)

@bp.route('/vaccine',methods=['POST'])
def vaccine():
    if(session.get('permission') != 'User'):
        abort(403)
    db = get_db()

    if request.method == 'POST':
        #post application for vaccine
        data = request.get_data()
        data = json.loads(data.decode("utf-8"))
        # username = data['username']
        medical_point_id = data['medical_point_id']
        time = data['time']
        manufacturer = data['manufacturer']
        vaccine_id = db.execute(
            'SELECT vaccine_id FROM User WHERE id = ?', (session.get('id'),)
            ).fetchone()
        if(vaccine_id['vaccine_id'] >= 0):
            vaccine = db.execute(
                'SELECT medical_point_id,status FROM Vaccine_record WHERE id = ?', (vaccine_id['vaccine_id'],)
                ).fetchone()
            if(vaccine['status'] == 1):
                res = Response(f"您在 {vaccine['medical_point_id']} 已有核酸预约未完成")
                abort(res)
        try:
            #not same with nucleic
            #not session.get('id')
            #but data['medical_point_id']
            if(manufacturer == "0"):
                db.execute(
                    'UPDATE Medical_point set vaccine_B = vaccine_B - 1 , vaccine_waiting = vaccine_waiting + 1 where id = ?',
                    (medical_point_id,),
                )
                vaccine_name = "vaccine_B"
            elif(manufacturer == "1"):
                db.execute(
                    'UPDATE Medical_point set vaccine_K = vaccine_K - 1 , vaccine_waiting = vaccine_waiting + 1 where id = ?',
                    (medical_point_id,),
                )
                vaccine_name = "vaccine_K"
            else:
                abort(400)
            
            db.execute(
                'INSERT INTO Vaccine_record (user_id,medical_point_id,status,manufacturer,time) VALUES (?, ?, ?, ?, ?)',
                (session.get('id'), medical_point_id, 1, manufacturer, time),
            )
            db.commit()
            id = db.execute(
                "SELECT last_insert_rowid() from Vaccine_record"
                ).fetchone()[0]
            db.execute(
                "UPDATE User set vaccine_id = ? where id = ?", 
                (id,session.get('id'),),
            )
            db.commit()
        except db.IntegrityError:
            abort(400)
        else:
            current_app.logger.info("User: "+str(session.get('id'))+" make vaccine_appointment to "+str(medical_point_id)+" type "+vaccine_name)
            return "success"
    abort(405)  #method not allowed


@bp.route('/vaccine-record',methods=['GET','POST'])
def vaccine_record():
    if(session.get('permission') != 'Medical_point'):
        abort(403)
    db = get_db()
    if request.method == 'GET':
        # return the unfinished records
        test_records = db.execute(
            'SELECT Vaccine_record.id,username,time,Vaccine_record.status FROM Vaccine_record join User WHERE medical_point_id = ? and Vaccine_record.status = 1 and user_id = User.id', 
            (session.get('id'),)
        ).fetchall()
        record_list = []
        for record in test_records:
            record_list.append({'id':record['id'],'username':record['username'],'time':record['time'],'result':record['status']})
        return jsonify({'record_list':record_list})

    if request.method == 'POST':
        # update vaccine result
        data = request.get_data()    
        data = json.loads(data.decode("utf-8"))
        record_ID = data['record_id']
        name = data['username']
        record = db.execute(
            'SELECT medical_point_id,status FROM Vaccine_record WHERE id = ?', (record_ID,)
            ).fetchone()
        if(record['medical_point_id'] != session.get('id')):
            abort(400)
        try:
            if record['status'] == 1:
                db.execute(
                    "UPDATE Medical_point set vaccine_waiting = vaccine_waiting - 1 where id = ?",
                    (record['medical_point_id'],),
                )
                db.execute(
                    "UPDATE User set vaccine_id = -1 WHERE id = ?",
                    (name,),
                )
            db.execute(
                "UPDATE Vaccine_record set status = ? where id = ?",
                (0,record_ID,),
            )
            db.commit()
        except db.IntegrityError:
            abort(400)
        else:
            current_app.logger.info("User: "+str(session.get('id'))+" vaccine_appointment "+str(record_ID)+" finish ")
            return "success"

@bp.route('/vaccine-history',methods=['GET'])
def vaccine_history():
    if(session.get('permission') != 'User'):
        abort(403)
    db = get_db()
    if request.method == 'GET':
        records = db.execute(
            'SELECT Medical_point.username,manufacturer,time,status FROM Vaccine_record join Medical_point WHERE user_id = ? and Medical_point.id = medical_point_id', 
            (session.get('id'),)
        ).fetchall()
        vaccine_history = []
        for record in records:
            vaccine_history.append({'medical_point':record['username'],'time':record['time'],'status':record['status'],'manufacturer':record['manufacturer']})
        return jsonify({'vaccine_history':vaccine_history})


@bp.route('/vaccine-cancel', methods=['DELETE'])
def vaccine_cancel():
    if request.method == 'DELETE':
        if(session.get('permission') != 'User'):
            abort(403)
        db = get_db()
        vaccine_id = db.execute(
            'SELECT vaccine_id FROM User WHERE id = ?', (session.get('id'),)
            ).fetchone()
        if(vaccine_id['vaccine_id'] >= 0):
            vaccine = db.execute(
                'SELECT manufacturer,medical_point_id,status FROM Vaccine_record WHERE id = ?', (vaccine_id['vaccine_id'],)
                ).fetchone()
            if(vaccine['status'] == 1):
                try:
                    db.execute(
                        "DELETE FROM Vaccine_record WHERE id = ?",
                        (vaccine_id['vaccine_id'],),
                    )
                    db.execute(
                        "UPDATE User set vaccine_id = -1 WHERE id = ?",
                        (session.get('id'),),
                    )
                    if vaccine['manufacturer'] == 0:
                        db.execute(
                            "UPDATE Medical_point set vaccine_B = vaccine_B + 1 , vaccine_waiting = vaccine_waiting - 1 where id = ?",
                            (vaccine['medical_point_id'],),
                        )
                    elif vaccine['manufacturer'] == 1:
                        db.execute(
                            "UPDATE Medical_point set vaccine_K = vaccine_K + 1 , vaccine_waiting = vaccine_waiting - 1 where id = ?",
                            (vaccine['medical_point_id'],),
                        )
                    db.commit()
                except db.IntegrityError:
                    abort(400)
                else:
                    current_app.logger.info("User: "+str(session.get('id'))+" vaccine_appointment "+str(vaccine_id['vaccine_id'])+" cancel ")
                    return "success"
        res = Response("当前无未完成预约")
        abort(res)
    abort(405)

@bp.route('/vaccine-add', methods=['GET','POST'])
def vaccine_add():
    db = get_db()
    if request.method == 'POST':
        if(session.get('permission') != 'Medical_point'):
            abort(403)
        data = request.get_data()    
        data = json.loads(data.decode("utf-8"))
        number = data['number']
        manufacturer = data['manufacturer']
        if int(number) < 0:
            abort(400)
        try:
            if(manufacturer == "0"):
                db.execute(
                    "UPDATE Medical_point set vaccine_B = vaccine_B + ? where id = ?",
                    (number,session.get('id'),),
                )
                vaccine_name = "vaccine_B"
            elif(manufacturer == "1"):
                db.execute(
                    "UPDATE Medical_point set vaccine_K = vaccine_K + ? where id = ?",
                    (number,session.get('id'),),
                )
                vaccine_name = "vaccine_K"
            else:
                abort(400)
            db.commit()
        except db.IntegrityError:
            abort(400)
        else:
            current_app.logger.info("Medical_point: "+str(session.get('id'))+" add vaccine "+str(number)+" type "+vaccine_name)
            return "success"
    elif request.method == 'GET':
        number = db.execute(
            'SELECT vaccine_B,vaccine_K FROM Medical_point WHERE id = ?', (session.get('id'),)
            ).fetchone()
        return jsonify({'vaccine_B':number['vaccine_B'],'vaccine_K':number['vaccine_K']})
    abort(405)